<?php

declare(strict_types=1);

namespace app\admin\controller;

use app\common\controller\AdminController;
use app\common\library\Oss as OssClient;
use app\common\model\OssFile;
use app\common\utils\JsonResponse;
use think\facade\Request;
use think\facade\Validate;
use think\App;
use think\helper\Arr;

class Oss extends AdminController
{
    protected OssClient $ossClient;
    protected OssFile $ossFileModel;

    public function __construct(App $app)
    {
        parent::__construct($app);
        $this->ossClient = new OssClient();
        $this->ossFileModel = new OssFile();
    }

    /**
     * 上传文件(全局上传方法)
     * @permission system:oss:upload
     */
    public function upload()
    {
        try {
            // 获取上传文件
            $file = Request::file('file');
            if (!$file) {
                return JsonResponse::error('请选择上传文件');
            }

            // 验证文件
            $validate = [];
            
            // 添加文件大小限制
            $validate['file'][] = 'fileSize:' . intval(env('UPLOAD_MAX_SIZE', 52428800));
            
            // 如果不允许全类型上传，则验证文件类型
            if (!env('UPLOAD_ALLOW_ALL', false)) {
                // 获取允许的文件类型
                $allowExts = array_merge(
                    explode(',', env('UPLOAD_IMAGE_EXT', '')),
                    explode(',', env('UPLOAD_VIDEO_EXT', '')),
                    explode(',', env('UPLOAD_AUDIO_EXT', '')),
                    explode(',', env('UPLOAD_DOCUMENT_EXT', '')),
                    explode(',', env('UPLOAD_ARCHIVE_EXT', ''))
                );
                $validate['file'][] = 'fileExt:' . implode(',', array_filter($allowExts));
            }

            // 验证文件
            $validate = Validate::rule($validate);
            if (!$validate->check(['file' => $file])) {
                $errorKey = array_key_first($validate->getError());
                return JsonResponse::error($validate->getError($errorKey));
            }

            // 获取文件信息
            $originalName = $file->getOriginalName(); // 原始文件名
            $ext = $file->getOriginalExtension(); // 文件扩展名
            $size = $file->getSize(); // 文件大小
            $mimeType = $file->getMime(); // MIME类型

            // 根据文件类型确定存储目录
            $fileType = $this->getFileType($ext, $mimeType);

            // 生成文件名: 年月日/文件类型/随机文件名.扩展名
            $path = Request::param('path', ''); // 目录路径
            if ($path) {
                if ($path === '/') $path = '';
                $fileName = $path . md5(uniqid((string)mt_rand(), true)) . '.' . $ext;
            } else {
                $fileName = date('Ymd') . '/' . $fileType . '/' . md5(uniqid((string)mt_rand(), true)) . '.' . $ext;
            }

            // 上传到OSS
            $result = $this->ossClient->uploadFile($file->getRealPath(), $fileName);
            if (!$result) {
                return JsonResponse::error('上传失败');
            }

            // 记录文件信息
            $data = [
                'file_name' => $originalName,
                'file_path' => $fileName,
                'file_url' => $result,
                'file_size' => $size,
                'file_ext' => $ext,
                'mime_type' => $mimeType,
                'upload_ip' => Request::ip()
            ];

            // 上传者信息
            $uploader = [
                'type' => 'admin',
                'id' => $this->adminId,
                'name' => $this->adminInfo['nickname'] ?? '未知管理员'
            ];

            // 其他扩展信息
            $extend = [
                'module' => Request::param('module', ''), // 上传模块
                'purpose' => Request::param('purpose', ''), // 上传用途
                'remark' => Request::param('remark', ''), // 备注说明
                'tags' => Request::param('tags', []), // 标签
                'related_id' => Request::param('related_id', 0), // 关联ID
            ];

            // 保存文件记录
            $this->ossFileModel->saveFile($data, $uploader, $extend);

            return JsonResponse::success([
                'url' => $result,
                'path' => $fileName
            ]);
        } catch (\Exception $e) {
            return JsonResponse::error($e->getMessage());
        }
    }

    /**
     * 根据文件类型获取存储目录
     * @param string $ext 文件扩展名
     * @param string $mimeType MIME类型
     * @return string
     */
    protected function getFileType(string $ext, string $mimeType): string
    {
        // 图片类型
        $imageExts = explode(',', env('UPLOAD_IMAGE_EXT', ''));
        if (in_array(strtolower($ext), $imageExts) || strpos($mimeType, 'image/') === 0) {
            return 'images';
        }

        // 视频类型
        $videoExts = explode(',', env('UPLOAD_VIDEO_EXT', ''));
        if (in_array(strtolower($ext), $videoExts) || strpos($mimeType, 'video/') === 0) {
            return 'videos';
        }

        // 音频类型
        $audioExts = explode(',', env('UPLOAD_AUDIO_EXT', ''));
        if (in_array(strtolower($ext), $audioExts) || strpos($mimeType, 'audio/') === 0) {
            return 'audios';
        }

        // 文档类型
        $docExts = explode(',', env('UPLOAD_DOCUMENT_EXT', ''));
        if (in_array(strtolower($ext), $docExts)) {
            return 'documents';
        }

        // 压缩包类型
        $archiveExts = explode(',', env('UPLOAD_ARCHIVE_EXT', ''));
        if (in_array(strtolower($ext), $archiveExts)) {
            return 'archives';
        }

        // 其他类型
        return 'others';
    }

    /**
     * 获取文件列表
     * @permission system:oss:getList
     */
    public function getList()
    {
        try {
            $prefix = Request::param('prefix', ''); // 目录前缀
            $marker = Request::param('marker', ''); // 起始文件的位置
            $maxKeys = Request::param('maxKeys', 100); // 每页数量，默认100
            $delimiter = '/'; // 使用 / 作为分隔符来模拟目录结构

            // 获取 OSS 文件列表
            $result = $this->ossClient->listObjects([
                'prefix' => $prefix,
                'marker' => $marker,
                'max-keys' => $maxKeys,
                'delimiter' => $delimiter
            ]);

            // 处理返回结果
            $data = [
                'files' => [], // 文件列表
                'dirs' => [], // 目录列表
                'prefix' => $prefix, // 当前目录
                'nextMarker' => $result->getNextMarker(), // 下一页的起始位置
                'isTruncated' => $result->getIsTruncated() === 'tr', // 是否还有更多数据
                'acl' => $this->ossClient->isPrivate()
            ];

            // 处理目录
            foreach ($result->getPrefixList() as $prefixInfo) {
                $dir = $prefixInfo->getPrefix();
                $data['dirs'][] = [
                    'name' => basename(rtrim($dir, '/')),
                    'path' => $dir
                ];
            }

            // 处理文件
            foreach ($result->getObjectList() as $object) {
                // 跳过当前目录
                if ($object->getKey() === $prefix) {
                    continue;
                }

                $data['files'][] = [
                    'name' => basename($object->getKey()),
                    'path' => $object->getKey(),
                    'size' => $object->getSize(),
                    'type' => $object->getType(),
                    'eTag' => $object->getETag(),
                    'storageClass' => $object->getStorageClass(),
                    'lastModified' => $object->getLastModified(),
                    'restoreInfo' => $object->getRestoreInfo(),
                    'ownerId' => $object->getOwner()->getId(),
                    'ownerDisplayName' => $object->getOwner()->getDisplayName()
                ];
            }

            return JsonResponse::success($data);
        } catch (\Exception $e) {
            return JsonResponse::error($e->getMessage());
        }
    }

    /**
     * 删除文件
     * @permission system:oss:delete
     */
    public function delete()
    {
        $path = Request::param('path');
        if (!$path) {
            return JsonResponse::error('请选择要删除的文件');
        }

        try {
            // 查询文件信息
            $files = $this->ossFileModel->where('file_path', $path)->select();
            if ($files->isEmpty()) {
                $this->ossClient->deleteObject($path);
                return JsonResponse::success();
            }

            // 删除OSS文件
            foreach ($files as $file) {
                $this->ossClient->deleteObject($file->file_path);
                $file->delete();
            }

            return JsonResponse::success();
        } catch (\Exception $e) {
            return JsonResponse::error($e->getMessage());
        }
    }

    /**
     * 删除文件夹
     * @permission system:oss:deleteDir
     */
    public function deleteDir()
    {
        $dir = Request::param('path');
        if (!$dir) {
            return JsonResponse::error('请选择要删除的文件夹');
        }

        try {
            // 确保目录以 / 结尾
            $dir = rtrim($dir, '/') . '/';

            // 递归删除目录下的所有文件和子目录
            $this->deleteDirectory($dir);

            return JsonResponse::success();
        } catch (\Exception $e) {
            return JsonResponse::error($e->getMessage());
        }
    }

    /**
     * 递归删除目录及其内容
     * @param string $dir 目录路径
     * @param array $deletedObjects 已删除的对象列表(用于批量删除)
     * @return void
     */
    protected function deleteDirectory(string $dir, array &$deletedObjects = [])
    {
        $nextMarker = '';
        
        do {
            // 列出当前目录下的所有对象
            $options = [
                'prefix' => $dir,
                'marker' => $nextMarker,
                'max-keys' => 1000,
                'delimiter' => '/' // 使用分隔符来区分目录
            ];
            
            $result = $this->ossClient->listObjects($options);
            
            // 处理子目录
            foreach ($result->getPrefixList() as $prefixInfo) {
                $subDir = $prefixInfo->getPrefix();
                // 递归删除子目录
                $this->deleteDirectory($subDir, $deletedObjects);
            }
            
            // 收集当前目录下的文件
            foreach ($result->getObjectList() as $object) {
                $objectKey = $object->getKey();
                $deletedObjects[] = $objectKey;
                
                // 当积累到1000个对象时进行一次批量删除
                if (count($deletedObjects) >= 1000) {
                    $this->ossClient->deleteObjects($deletedObjects);
                    // 清空已删除的对象列表
                    $deletedObjects = [];
                }
            }
            
            $nextMarker = $result->getNextMarker();
        } while ($result->getIsTruncated() === 'true');
        
        // 删除剩余的对象
        if (!empty($deletedObjects)) {
            $this->ossClient->deleteObjects($deletedObjects);
        }
        
        // 最后删除目录本身
        $this->ossClient->deleteObject($dir);
        
        // 删除数据库中的记录
        $this->ossFileModel->where('file_path', 'like', $dir . '%')->delete();
    }

    /**
     * 创建文件夹
     * @permission system:oss:createFolder
     */
    public function createFolder()
    {
        try {
            $params = Request::post();
            
            // 验证参数
            $validate = Validate::rule([
                'path' => 'require|string',
                'name' => 'require|string|regex:/^[a-zA-Z0-9_\-\/\x{4e00}-\x{9fa5}]+$/u'
            ])->message([
                'path.require' => '请指定目录路径',
                'name.require' => '请输入文件夹名称',
                'name.regex' => '文件夹名称只能包含字母、数字、下划线、中划线和中文'
            ]);

            if (!$validate->check($params)) {
                $errorKey = array_key_first($validate->getError());
                return JsonResponse::error($validate->getError($errorKey));
            }

            // 处理路径
            $path = trim($params['path'], '/');
            $name = trim($params['name'], '/');
            $folderPath = $path ? $path . '/' . $name . '/' : $name . '/';

            // 检查文件夹是否已存在
            if ($this->ossClient->doesObjectExist($folderPath)) {
                return JsonResponse::error('文件夹已存在');
            }

            // 创建空文件夹（OSS通过创建以/结尾的空对象来模拟文件夹）
            $result = $this->ossClient->putObject('', $folderPath);
            if (!$result) {
                return JsonResponse::error('创建文件夹失败');
            }

            return JsonResponse::success([
                'path' => $folderPath
            ]);
        } catch (\Exception $e) {
            return JsonResponse::error($e->getMessage());
        }
    }

    /**
     * 获取文件下载链接
     * @permission system:oss:getDownloadUrl
     */
    public function getDownloadUrl()
    {
        $path = Request::param('path');
        if (!$path) {
            return JsonResponse::error('请选择要下载的文件');
        }

        try {
            // 检查文件是否存在
            if (!$this->ossClient->doesObjectExist($path)) {
                return JsonResponse::error('文件不存在');
            }

            // 获取文件信息
            $fileInfo = $this->ossClient->getObjectMeta($path);
            if (!$fileInfo) {
                return JsonResponse::error('获取文件信息失败');
            }

            // 生成下载链接,默认1小时有效
            $expireTime = Request::param('expire_time', 3600);
            $url = $this->ossClient->getFileUrl($path, intval($expireTime));

            // 获取文件记录
            $fileRecord = $this->ossFileModel->where('file_path', $path)->find();

            return JsonResponse::success([
                'url' => $url,
                'file_name' => $fileRecord ? $fileRecord->file_name : basename($path),
                'file_size' => $fileInfo['content-length'] ?? 0,
                'expire_time' => time() + $expireTime
            ]);
        } catch (\Exception $e) {
            return JsonResponse::error($e->getMessage());
        }
    }

    /**
     * 归获取文件夹信息
     * @param string $path 文件夹路径
     * @return array
     */
    protected function getFolderStats($path)
    {
        $stats = [
            'file_count' => 0,
            'folder_count' => 0,
            'total_size' => 0
        ];

        try {
            $nextMarker = '';
            
            do {
                // 列出当前目录下的所有对象
                $options = [
                    'prefix' => rtrim($path, '/') . '/',
                    'marker' => $nextMarker,
                    'max-keys' => 1000,
                    'delimiter' => '/' // 使用分隔符区���目录
                ];
                
                $result = $this->ossClient->listObjects($options);
                
                // 处理子目录
                foreach ($result->getPrefixList() as $prefixInfo) {
                    $subDir = $prefixInfo->getPrefix();
                    // 跳过当前目录
                    if ($subDir === rtrim($path, '/') . '/') {
                        continue;
                    }
                    $stats['folder_count']++;
                    
                    // 递归获取子目录的统计信息
                    $subStats = $this->getFolderStats($subDir);
                    $stats['file_count'] += $subStats['file_count'];
                    $stats['folder_count'] += $subStats['folder_count'];
                    $stats['total_size'] += $subStats['total_size'];
                }
                
                // 处理文件
                foreach ($result->getObjectList() as $object) {
                    $objectKey = $object->getKey();
                    // 跳过目录对象本身
                    if ($objectKey === rtrim($path, '/') . '/') {
                        continue;
                    }
                    $stats['file_count']++;
                    $stats['total_size'] += $object->getSize();
                }
                
                $nextMarker = $result->getNextMarker();
            } while ($result->getIsTruncated() === 'true');
            
            return $stats;
        } catch (\Exception $e) {
            return $stats;
        }
    }

    /**
     * 获取文件夹信息
     * @permission system:oss:getFolderInfo
     */
    public function getFolderInfo()
    {
        // 验证参数
        $path = Request::param('path', '/');
        
        try {
            // 规范化路径格式
            $path = '/' . trim($path, '/');
            if ($path !== '/') {
                $path .= '/';
            }
            
            // 检查文件夹是否存在(根目录默认存在)
            $ossPath = ltrim($path, '/');
            if ($path !== '/') {
                // 获取目录列表检查是否存在文件
                $options = [
                    'prefix' => $ossPath,
                    'max-keys' => 1,
                    'delimiter' => '/'
                ];
                $result = $this->ossClient->listObjects($options);
                // 如果没有任何对象且没有子目录,则认为目录不存在
                if (count($result->getObjectList()) === 0 && count($result->getPrefixList()) === 0) {
                    return JsonResponse::error('文件夹不存在');
                }
            }

            // 获取文件夹基本信息
            $info = [
                'name' => $path === '/' ? 'root' : basename(rtrim($path, '/')),
                'path' => $path,
                'parent_path' => $path === '/' ? '' : dirname($path),
                'created_time' => date('Y-m-d H:i:s'),
                'file_count' => 0,
                'folder_count' => 0,
                'total_size' => 0
            ];

            // 获取文件夹统计信息
            $stats = $this->getFolderStats($ossPath);
            $info = array_merge($info, $stats);

            // 添加额外信息
            $info['is_root'] = $path === '/';
            $info['full_path'] = rtrim(env('OSS_BUCKET', ''), '/') . $path;

            return JsonResponse::success($info);
        } catch (\Exception $e) {
            return JsonResponse::error($e->getMessage());
        }
    }

    /**
     * 获取文件信息
     * @permission system:oss:getFileInfo
     */
    public function getFileInfo()
    {
        // 验证参数
        $path = Request::param('path');
        if (empty($path)) {
            return JsonResponse::error('文件路径不能为空');
        }

        try {
            // 确保路径以/开头
            $path = '/' . ltrim($path, '/');
            $ossPath = ltrim($path, '/');
            
            // 检查文件是否存在
            if (!$this->ossClient->doesObjectExist($ossPath)) {
                return JsonResponse::error('文件不存在');
            }

            // 获取文件元信息
            $meta = $this->ossClient->getObjectMeta($ossPath);
            if (!$meta) {
                return JsonResponse::error('获取文件信息失败');
            }

            // 获取文件记录
            $fileRecord = $this->ossFileModel->where('file_path', $ossPath)->find();

            // 获取文件扩展名和MIME类型
            $extension = pathinfo($path, PATHINFO_EXTENSION);
            $mimeType = $meta['content-type'] ?? '';
            $fileType = $this->getFileType($extension, $mimeType);

            // 构建基本文件信息
            $info = [
                'name' => basename($path),
                'path' => $path,
                'url' => $this->ossClient->getFileUrl($ossPath, 3600),
                'size' => $meta['content-length'] ?? 0,
                'size_format' => $this->formatSize($meta['content-length'] ?? 0),
                'type' => $fileType,
                'mime_type' => $mimeType,
                'extension' => $extension,
                'created_time' => $fileRecord ? $fileRecord->create_time : date('Y-m-d H:i:s', strtotime($meta['last-modified'] ?? '')),
                'updated_time' => date('Y-m-d H:i:s', strtotime($meta['last-modified'] ?? '')),
                'etag' => trim($meta['etag'] ?? '', '"'),
                'storage_class' => $meta['x-oss-storage-class'] ?? 'Standard',
                'hash' => $meta['content-md5'] ?? '',
            ];

            // 获取图片特有信息
            if ($fileType === 'images') {
                try {
                    // 获取图片信息
                    $options = [
                        'x-oss-process' => 'image/info'
                    ];
                    $imageInfo = $this->ossClient->getObjectContent($ossPath, $options);
                    if ($imageInfo) {
                        $imageData = json_decode($imageInfo, true);
                        if ($imageData) {
                            $info['image_info'] = [
                                'width' => $imageData['ImageWidth']['value'] ?? 0,
                                'height' => $imageData['ImageHeight']['value'] ?? 0,
                                'format' => $imageData['Format']['value'] ?? '',
                                'color_mode' => $imageData['ColorMode']['value'] ?? '',
                                'animation' => $imageData['AnimationFrames']['value'] ?? 0,
                                'quality' => $imageData['Quality']['value'] ?? 0
                            ];
                        }
                    }
                } catch (\Exception $e) {
                    // 忽略图片信息获取失败
                }
            }

            // 获取视频特有信息
            if ($fileType === 'videos') {
                try {
                    // 使用 OSS 视频信息接口获取详细信
                    $options = [
                        'x-oss-process' => 'video/info'
                    ];
                    $videoInfo = $this->ossClient->getObjectContent($ossPath, $options);
                    if ($videoInfo) {
                        $videoData = json_decode($videoInfo, true);
                        if ($videoData) {
                            // 获取第一个视频流和音频流
                            $videoStream = $videoData['VideoStreams'][0] ?? null;
                            $audioStream = $videoData['AudioStreams'][0] ?? null;

                            $info['video_info'] = [
                                // 基本信息
                                'format' => $videoData['FormatName'] ?? '',
                                'format_long_name' => $videoData['FormatLongName'] ?? '',
                                'duration' => floatval($videoData['Duration'] ?? 0),
                                'duration_format' => $this->formatDuration($videoData['Duration'] ?? 0),
                                'size' => intval($videoData['Size'] ?? 0),
                                'bitrate' => intval($videoData['Bitrate'] ?? 0),
                                'stream_count' => intval($videoData['StreamCount'] ?? 0),
                                
                                // 视频流信息
                                'video' => $videoStream ? [
                                    'width' => intval($videoStream['Width'] ?? 0),
                                    'height' => intval($videoStream['Height'] ?? 0),
                                    'codec' => $videoStream['CodecName'] ?? '',
                                    'codec_long_name' => $videoStream['CodecLongName'] ?? '',
                                    'profile' => $videoStream['Profile'] ?? '',
                                    'level' => intval($videoStream['Level'] ?? 0),
                                    'fps' => $videoStream['AverageFrameRate'] ?? '',
                                    'frame_count' => intval($videoStream['FrameCount'] ?? 0),
                                    'bitrate' => intval($videoStream['Bitrate'] ?? 0),
                                    'duration' => floatval($videoStream['Duration'] ?? 0),
                                    'pixel_format' => $videoStream['PixelFormat'] ?? '',
                                    'bit_depth' => intval($videoStream['BitDepth'] ?? 0),
                                    'display_aspect_ratio' => $videoStream['DisplayAspectRatio'] ?? '',
                                    'sample_aspect_ratio' => $videoStream['SampleAspectRatio'] ?? '',
                                    'time_base' => $videoStream['TimeBase'] ?? ''
                                ] : null,
                                
                                // 音频流信息
                                'audio' => $audioStream ? [
                                    'codec' => $audioStream['CodecName'] ?? '',
                                    'codec_long_name' => $audioStream['CodecLongName'] ?? '',
                                    'channels' => intval($audioStream['Channels'] ?? 0),
                                    'channel_layout' => $audioStream['ChannelLayout'] ?? '',
                                    'sample_rate' => intval($audioStream['SampleRate'] ?? 0),
                                    'sample_format' => $audioStream['SampleFormat'] ?? '',
                                    'bitrate' => intval($audioStream['Bitrate'] ?? 0),
                                    'duration' => floatval($audioStream['Duration'] ?? 0),
                                    'frame_count' => intval($audioStream['FrameCount'] ?? 0),
                                    'time_base' => $audioStream['TimeBase'] ?? ''
                                ] : null
                            ];

                            // 添加缩略图URL
                            $info['video_info']['thumbnail'] = [
                                'url' => $this->ossClient->getFileUrl($ossPath, 3600, [
                                    'x-oss-process' => 'video/snapshot,t_1000,f_jpg,w_0,h_0,m_fast'
                                ]),
                                'width' => intval($videoData['VideoWidth'] ?? 0),
                                'height' => intval($videoData['VideoHeight'] ?? 0)
                            ];
                        }
                    }
                } catch (\Exception $e) {
                    // 忽略视频信息获取失败
                }
            }

            // 获取音频特有信息
            if ($fileType === 'audios') {
                try {
                    // 使用 OSS 音频信息接口获取详细信息
                    $options = [
                        'x-oss-process' => 'audio/info'
                    ];
                    $audioInfo = $this->ossClient->getObjectContent($ossPath, $options);
                    if ($audioInfo) {
                        $audioData = json_decode($audioInfo, true);

                        if ($audioData) {
                            // 获取第一个音频流
                            $audioStream = $audioData['AudioStreams'][0] ?? null;

                            $info['audio_info'] = [
                                // 基本信息
                                'format' => $audioData['FormatName'] ?? '',
                                'format_long_name' => $audioData['FormatLongName'] ?? '',
                                'duration' => floatval($audioData['Duration'] ?? 0),
                                'duration_format' => $this->formatDuration($audioData['Duration'] ?? 0),
                                'size' => intval($audioData['Size'] ?? 0),
                                'bitrate' => intval($audioData['Bitrate'] ?? 0),
                                'stream_count' => intval($audioData['StreamCount'] ?? 0),
                                
                                // 音频流信息
                                'audio' => $audioStream ? [
                                    'codec' => $audioStream['CodecName'] ?? '',
                                    'codec_long_name' => $audioStream['CodecLongName'] ?? '',
                                    'channels' => intval($audioStream['Channels'] ?? 0),
                                    'channel_layout' => $audioStream['ChannelLayout'] ?? '',
                                    'sample_rate' => intval($audioStream['SampleRate'] ?? 0),
                                    'sample_format' => $audioStream['SampleFormat'] ?? '',
                                    'bitrate' => intval($audioStream['Bitrate'] ?? 0),
                                    'duration' => floatval($audioStream['Duration'] ?? 0),
                                    'time_base' => $audioStream['TimeBase'] ?? ''
                                ] : null,
                                
                                // 元数据信息
                                'metadata' => [
                                    'title' => $audioData['Title'] ?? '',
                                    'artist' => $audioData['Artist'] ?? '',
                                    'album' => $audioData['Album'] ?? ''
                                ],
                            ];
                        }
                    }
                } catch (\Exception $e) {
                    // 忽略音频信息获取失败
                }
            }

            // 如果有数据库记录，补充更多信息
            if ($fileRecord) {
                $info['original_name'] = $fileRecord->file_name;
                $info['uploader'] = [
                    'type' => $fileRecord->uploader_type,
                    'id' => $fileRecord->uploader_id,
                    'name' => $fileRecord->uploader_name
                ];
                $info['upload_ip'] = $fileRecord->upload_ip;
                $info['module'] = $fileRecord->module;
                $info['purpose'] = $fileRecord->purpose;
                $info['remark'] = $fileRecord->remark;
                $info['tags'] = $fileRecord->tags ? explode(',', $fileRecord->tags) : [];
                $info['related_id'] = $fileRecord->related_id;
            }

            return JsonResponse::success($info);
        } catch (\Exception $e) {
            return JsonResponse::error($e->getMessage());
        }
    }

    /**
     * 格式化文件大小
     * @param int|string $size 文件大小(字节)
     * @return string
     */
    protected function formatSize($size)
    {
        // 确保 $size 是数字
        $size = floatval($size);
        
        $units = ['B', 'KB', 'MB', 'GB', 'TB'];
        $index = 0;
        while ($size >= 1024 && $index < count($units) - 1) {
            $size /= 1024;
            $index++;
        }
        return round($size, 2) . ' ' . $units[$index];
    }

    /**
     * 格式化视频时长
     * @param float $seconds 秒数
     * @return string
     */
    protected function formatDuration($seconds)
    {
        $seconds = floatval($seconds);
        $hours = floor($seconds / 3600);
        $minutes = floor(($seconds % 3600) / 60);
        $seconds = $seconds % 60;
        
        if ($hours > 0) {
            return sprintf('%02d:%02d:%02d', $hours, $minutes, $seconds);
        } else {
            return sprintf('%02d:%02d', $minutes, $seconds);
        }
    }

    /**
     * 获取文件URL
     * @param string $path 文件路径
     * @return string
     */
    protected function getFileUrl($path)
    {
        try {
            // 检查文件是否存在
            if (!$this->ossClient->doesObjectExist($path)) {
                return '';
            }
            
            // 生成文件URL，默认有效期1小时
            return $this->ossClient->getFileUrl($path, 3600);
        } catch (\Exception $e) {
            return '';
        }
    }

    /**
     * 获取文件大小
     * @param string $path 文件路径
     * @return int
     */
    protected function getFileSize($path)
    {
        try {
            // 获取文件元信息
            $meta = $this->ossClient->getObjectMeta($path);
            return isset($meta['content-length']) ? intval($meta['content-length']) : 0;
        } catch (\Exception $e) {
            return 0;
        }
    }

    /**
     * 获取文件MIME类型
     * @param string $path 文件路径
     * @return string
     */
    protected function getFileMimeType($path)
    {
        try {
            // 获取文件元信息
            $meta = $this->ossClient->getObjectMeta($path);
            return $meta['content-type'] ?? '';
        } catch (\Exception $e) {
            return '';
        }
    }

    /**
     * 获取文件预览链接
     * @permission system:oss:getPreviewUrl
     */
    public function getPreviewUrl()
    {
        $path = Request::param('path');
        if (!$path) {
            return JsonResponse::error('请选择要预览的文件');
        }

        try {
            // 确保路径以/开头
            $path = '/' . ltrim($path, '/');
            $ossPath = ltrim($path, '/');
            
            // 检查文件是否存在
            if (!$this->ossClient->doesObjectExist($ossPath)) {
                return JsonResponse::error('文件不存在');
            }

            // 获取文件信息
            $meta = $this->ossClient->getObjectMeta($ossPath);
            if (!$meta) {
                return JsonResponse::error('获取文件信息失败');
            }

            // 获取文件类型
            $extension = pathinfo($path, PATHINFO_EXTENSION);
            $mimeType = $meta['content-type'] ?? '';
            $fileType = $this->getFileType($extension, $mimeType);

            // 生成预览链接,默认1小时有效
            $url = $this->ossClient->getFileUrl($ossPath, 3600);

            return JsonResponse::success([
                'url' => $url,
                'type' => $fileType,
                'mime_type' => $mimeType,
                'size' => intval($meta['content-length'] ?? 0),
                'size_format' => $this->formatSize($meta['content-length'] ?? 0),
                'extension' => $extension
            ]);
        } catch (\Exception $e) {
            return JsonResponse::error($e->getMessage());
        }
    }
}
